package com.merak.rebot.python;

import com.alibaba.fastjson.JSON;
import com.ctg.behavior.utils.ReturnUtil;
import com.merak.rebot.common.PythonStatus;
import com.merak.rebot.common.UploaderFile;
import com.merak.rebot.config.MRebotsConfig;
import com.merak.rebot.config.UploaderConfig;
import com.merak.rebot.utils.FileUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

@Component
@Slf4j
public class UploadFileExecutor {

    @Autowired
    private UploaderConfig upConfig;
    @Autowired
    private MRebotsConfig mrebotsConfig;
    @Autowired
    private MerakPythonExecutor merakPythonExecutor;

    public ReturnUtil doExecutor(UploaderFile uploaderFile){
        try {
            log.info("调用文件上传");
            String endsPath = uploaderFile.getFileDir();
            //文件实时目录，用于不存在自动创建
            String path = mrebotsConfig.getRebots().getPath()+File.separator+endsPath;
            //做下基本校验
            ReturnUtil result = doCheck(uploaderFile);
//            File newFile = new File(path + File.separator + uploaderFile.getFiles().get(0).getOriginalFilename());
//            //判断是否存在文件，存在则删除
//            newFile.deleteOnExit();
            //删除状态文件
            new File(path + File.separator + uploaderFile.getFiles().get(0).getOriginalFilename()+".status").deleteOnExit();
            if(!ReturnUtil.SUCCESSFUL_CODE.equals(result.getCode())){
                return result;
            }
//            //文件存放路径，最后一层目录存在要返回文件已执行
//            String path = localPath;
            //获取文件list
            List<MultipartFile> files = uploaderFile.getFiles();
            //判断该文件下的上级文件夹是否存在 不存在创建
            FileUtil.isDirectory(path);
            for (MultipartFile file : files) {
                //上传文件
                if(new File(path+File.separator+file.getOriginalFilename()).exists()) {
                    merakPythonExecutor.moveParamFile(path + File.separator, file.getOriginalFilename(), path + File.separator + "history" + File.separator, FileUtil.getBakFileName(file.getOriginalFilename()));
                }
                file.transferTo(new File(path+File.separator+file.getOriginalFilename()));//这一步结束就上传成功了。
                //记录就绪状态文件
                if(file.getOriginalFilename().endsWith(".py")) {
                    PythonStatus pythonStatus = new PythonStatus();
                    pythonStatus.setName(file.getOriginalFilename());
                    try {
                        FileUtils.writeStringToFile(new File(path + File.separator + pythonStatus.getName()+".status"), JSON.toJSONString(pythonStatus), StandardCharsets.UTF_8);
                    } catch (IOException e) {
                        log.info(e.getMessage(), e);
                    }
                }
            }
//            //==========================================================================分割线下面是我自己的业务需求，将其他信息和文件的名称，路径保存到数据库。
//            //保存文件到数据库 这个是我自己业务需要的，如果只是单纯的上传文件到一个位置 则下面的代码就可以不同写了
//
//            上传信息保存
//            saveFdFile(uploaderFile);
            return ReturnUtil.success("文件上传成功",null);
        } catch (Exception e) {
            log.error("文件上传失败",e);
            return ReturnUtil.error("文件上传失败");
        }
    }

    public ReturnUtil doConfigExecutor(UploaderFile uploaderFile){
        try {
            log.info("调用配置文件上传");
            String endsPath = uploaderFile.getFileDir();
            //文件实时目录，用于不存在自动创建
            String path = mrebotsConfig.getRebots().getPath()+File.separator+endsPath;
            //做下基本校验
            ReturnUtil result = doCheck(uploaderFile);
            if(!ReturnUtil.SUCCESSFUL_CODE.equals(result.getCode())){
                return result;
            }
            //获取文件list
            List<MultipartFile> files = uploaderFile.getFiles();
            //判断该文件下的上级文件夹是否存在 不存在创建
            FileUtil.isDirectory(path);
            for (MultipartFile file : files) {
                //上传文件
                if(new File(path+File.separator+file.getOriginalFilename()).exists()) {
                    merakPythonExecutor.moveParamFile(path + File.separator, file.getOriginalFilename(), path + File.separator + "history" + File.separator, FileUtil.getBakFileName(file.getOriginalFilename()));
                }
                file.transferTo(new File(path+File.separator+file.getOriginalFilename()));//这一步结束就上传成功了。
            }
            return ReturnUtil.success("文件上传成功",null);
        } catch (Exception e) {
            log.error("配置文件上传失败",e);
            return ReturnUtil.error("配置文件上传失败");
        }
    }

    /**
     * 做基本校验
     * @param uploaderFile
     * @return ReturnUtil
     */
    private ReturnUtil doCheck(UploaderFile uploaderFile) {
        //校验文件上传个数
        List<MultipartFile> files = uploaderFile.getFiles();
        if(CollectionUtils.isEmpty(files)){
            return ReturnUtil.error("文件上传个数必须大于0");
        }else if(files.size()>upConfig.getMaxSize()){
            return ReturnUtil.error("文件上传个数不能大于" + upConfig.getMaxSize());
        }
        return ReturnUtil.success();
    }

    /**
     * 分页查询列收明细表，写入本地临时文件
     * @return 返回一个本地临时文件
     * @throws IOException
     */
    private void saceLocalFile(String datafilePath, String dataFileName, UploaderFile uploaderFile){
        try{
            FileUtil.isDirectory(datafilePath);
            File file = new File(datafilePath + File.separator+dataFileName);
            if(!file.exists()){
                try {
                    file.createNewFile();
                } catch (IOException e) {
                    log.error("文件创建失败",e);
                    throw e;
                }
            }
            String s = null;
            try {
                s = genLineStr(uploaderFile);
            } catch (Exception e) {
                log.error("拼装FTP文件异常:{}，当前处理EnterpriseAccCheck:{},直接返回",e.toString(),uploaderFile);
                e.printStackTrace();
            }
            List<String> lines = new ArrayList<>();
            if(!StringUtils.isEmpty(s)) {
                lines.add(s);
            }
            FileUtil.writeFile(datafilePath+File.separator+dataFileName,lines,true);
            log.info("当前生成行数据:{}",s);
        }catch (IOException e){
            log.error("saveFdFile失败。文件名{}。uploaderFile is {}",datafilePath+File.separator+dataFileName,uploaderFile,e);
        }
    }

    /**
     * 生成行数据字符串
     * @param uploaderFile  数据库数据条目
     * @return 返回一行待插入数据字符串
     */
    private String genLineStr(UploaderFile uploaderFile) {
        //拼装数据
        StringBuilder sb = new StringBuilder();
        sb.append(FileUtil.ches(uploaderFile.getUuid())).append("|");
        sb.append(FileUtil.ches(uploaderFile.getFileName())).append("|");
        sb.append(FileUtil.ches(uploaderFile.getVersionNumber())).append("|");
        sb.append(FileUtil.ches(uploaderFile.getRemark())).append("|");
        sb.append(FileUtil.ches(uploaderFile.getState())).append("|");
        sb.append(FileUtil.ches(uploaderFile.getCreateDate())).append("|");
        sb.append(FileUtil.ches(uploaderFile.getUpdateDate()));
        return sb.toString();
    }

//    public ReturnUtil showUploaderInfo(CtShowUpParam ctShowUpParam) {
//        List<String> lines = FileUtil.readFile(new File(upConfig.getDatafilePath() + File.separator + upConfig.getDataFileName()));
//        List<UploaderFile> list = new ArrayList<>();
//        for (String line : lines) {
//            if(StringUtils.isNotEmpty(line)&&line.split("\\|").length>=7){
//                //筛选数据
//                if(ctShowUpParam.getVersionNumber().contains(ctShowUpParam.getVersionNumber())) {
//                    addUploaderInfo(line);
//                }
//            }
//        }
//        return null;
//    }

    private void addUploaderInfo(String line) {
        String[] split = line.split("\\|");
    }
}
